package com.violet.service.app.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.violet.domain.dto.app.AAddressDto;
import com.violet.domain.po.Address;
import com.violet.domain.vo.app.AAddressVo;
import com.violet.mapper.AddressMapper;
import com.violet.service.app.AAddressService;
import com.violet.utils.TransitionUtils;
import com.violet.utils.UserContent;
import lombok.RequiredArgsConstructor;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
@RequiredArgsConstructor
public class AAddressServiceImpl extends ServiceImpl<AddressMapper, Address>
        implements AAddressService {

    private final TransitionUtils<AAddressDto, Address, AAddressVo> transition;

    @Override
    public List<AAddressVo> getAll() {
        List<Address> addresses = baseMapper.selectList(new LambdaQueryWrapper<Address>().eq(Address::getUserId, UserContent.getUserId()));
        return addresses.stream().map(address -> transition.transition(address, AAddressVo.class)).toList();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AAddressVo create(AAddressDto dto) {
        Address address = transition.transition(dto, Address.class).setUserId(UserContent.getUserId());
        try {
            baseMapper.insert(address);
        }
        catch (DuplicateKeyException e) {throw new RuntimeException("地址已存在");}
        return transition.transition(address, AAddressVo.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteById(String id) {
        Address address = baseMapper.getByIdWithPessimisticLock(id, UserContent.getUserId());
        if (address == null) throw new RuntimeException("地址不存在");
        return baseMapper.deleteById(address) == 1;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AAddressVo updateById(String id, AAddressDto dto) {
        Address address = baseMapper.getByIdWithPessimisticLock(id, UserContent.getUserId());
        if (address == null) throw new RuntimeException("地址不存在");
        transition.copy(dto, address);
        baseMapper.updateById(address);
        return transition.transition(address, AAddressVo.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean setDefault(String id) {
        // 查询并加锁
        Address existingAddress = baseMapper.getByIdWithPessimisticLock(id, UserContent.getUserId());
        if (existingAddress != null) {
            // 将所有不是默认地址的设置为 false
            baseMapper.update(null,
                new LambdaUpdateWrapper<Address>()
                    .set(Address::getIsDefault, false)
                    .eq(Address::getUserId, UserContent.getUserId())
            );
            // 再将默认地址设置为 true
            baseMapper.updateById(existingAddress.setIsDefault(true));
            return true;
        }
        else {throw new RuntimeException("没有找到地址或不属于用户");}
    }

}
